package com.yanqu.road.server.gameplayer.module.palace;

import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.estatewar.UserEstateWarData;
import com.yanqu.road.entity.estatewar.palace.PalaceBattleRecord;
import com.yanqu.road.entity.estatewar.palace.PalaceFloorConfig;
import com.yanqu.road.entity.estatewar.palace.UserPalaceData;
import com.yanqu.road.entity.log.LogPalaceWorship;
import com.yanqu.road.logic.bussiness.palace.PalaceBussiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.pb.PalacePb;
import com.yanqu.road.pb.estatewar.EstateWarProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.gameplayer.module.player.EstateWarModule;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.manger.log.LogMgr;
import com.yanqu.road.server.manger.palace.PalaceActivity;
import com.yanqu.road.server.manger.palace.PalaceActivityMgr;
import com.yanqu.road.server.manger.player.EstateWarMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.pb.EstateWarPb;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.LocalDateTimeHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class PalaceModule extends GeneralModule {
    private UserPalaceData userPalaceData;
    private List<PalaceBattleRecord> palaceBattleRecordList = new ArrayList<>();

    public PalaceModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        PalaceActivity palaceActivity = PalaceActivityMgr.getInTimePalaceActivity();
        if(null != palaceActivity){
            palaceBattleRecordList = PalaceBussiness.getPalaceBattleRecordList(palaceActivity.getPalaceActivityId(), player.getUserId(),
                    GameConfig.PALACE_BATTLE_RECORD_MAX_COUNT);
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return true;
    }

    @Override
    public boolean saveData() {
        List<PalaceBattleRecord> tempList;
        synchronized (palaceBattleRecordList){
            tempList = new ArrayList<>(palaceBattleRecordList);
        }
        for(PalaceBattleRecord data :tempList){
            if(data.isInsertOption()){
                PalaceBussiness.addPalaceBattleRecord(data);
            }
        }
        return true;
    }

    @Override
    public void afterLogin() {
        if(SystemOpenMgr.systemOpen(player, eSystemId.PalaceActivity.getValue())) {
            palaceInit();
        }
        syncActivityConfig();
    }

    public void palaceInit(){
        checkUserData();
        //同步玩家数据
        syncUserData();
        //同步战斗记录
        syncBattleRecord(getPalaceBattleRecordList(), true);
        //同步申请列表
        PalaceActivity palaceActivity = PalaceActivityMgr.getInTimePalaceActivity();
        if(null != palaceActivity) {
            palaceActivity.syncPalaceUserData(player);
            palaceActivity.getPalaceAideJoinApplyList(player);
        }
        //检测一下皇宫皮肤
        checkEstateSkin();
    }

    private void checkEstateSkin(){
        EstateWarModule estateWarModule = player.getModule(EstateWarModule.class);
        UserEstateWarData userEstateWarData = estateWarModule.getUserEstateWarData();
        boolean isChange = EstateWarMgr.checkEstatePalaceSkin(userEstateWarData);
        if(isChange){//需要替换皮肤
            estateWarModule.syncUserEstateWarData();
        }
    }

    private void checkUserData(){
        PalaceActivity palaceActivity = PalaceActivityMgr.getInTimePalaceActivity();
        if (null != palaceActivity) {
            if(null == userPalaceData || userPalaceData.getActivityId() != palaceActivity.getPalaceActivityId()){
                if(null != userPalaceData && userPalaceData.getActivityId() != palaceActivity.getPalaceActivityId()) {
                    palaceBattleRecordList = new ArrayList<>();
                }
                UserPalaceData tempData = palaceActivity.getUserPalaceData(player.getUserId());
                if (null == tempData) {
                    tempData = palaceActivity.initUserPalaceData(player);
                }
                userPalaceData = tempData;
                if(userPalaceData.getPos() > 0){
                    PalaceFloorConfig palaceFloorConfig = palaceActivity.getPalaceFloorConfig(userPalaceData.getPos());
                    if(null != palaceFloorConfig) {
                        int estateSkinId = palaceFloorConfig.getSkinsReward();
                        EstateWarModule estateWarModule = player.getModule(EstateWarModule.class);
                        estateWarModule.unlockEstateSkin(estateSkinId);
                    }
                }
            }
        }else {
            userPalaceData = null;
            palaceBattleRecordList = new ArrayList<>();
        }
    }

    public UserPalaceData getUserPalaceData() {
        return userPalaceData;
    }

    public void syncUserData(){
        EstateWarProto.PalaceUserDataMsg.Builder msg = PalacePb.parsePalaceUserDataMsg(userPalaceData);
        if(null != msg){
            player.sendPacket(Protocol.U_PALACE_USER_DATA, msg);
        }
    }

    public void syncActivityConfig(){
        PalaceActivity palaceActivity = PalaceActivityMgr.getInTimePalaceActivity();
        if(null != palaceActivity) {
            EstateWarProto.PalaceActivityMsg.Builder activityMsg = EstateWarPb.parsePalaceActivityMsg(palaceActivity.getPalaceFloorConfigList(),
                    player.getLanguage());
            player.sendPacket(Protocol.U_PALACE_CONFIG_SYNC, activityMsg);
        }
    }

    public void syncBattleRecord(List<PalaceBattleRecord> battleRecordList, boolean isLogin){
        EstateWarProto.PalaceBattleRecordListMsg.Builder listMsg = PalacePb.parsePalaceBattleRecordListMsg(battleRecordList);
        if(isLogin){
            player.sendPacket(Protocol.U_PALACE_BATTLE_RECORD_LIST, listMsg);
        }else {
            player.sendPacket(Protocol.U_PALACE_BATTLE_RECORD_SYNC, listMsg);
        }
    }

    public void syncBattleRecord(PalaceBattleRecord palaceBattleRecord){
        if(null != palaceBattleRecord){
            List<PalaceBattleRecord> syncList = new ArrayList<>();
            syncList.add(palaceBattleRecord);
            syncBattleRecord(syncList, false);
        }
    }

    /**
     * 描述：设置幕宾加入设置
     * 作者：zrq
     * 时间：2022/2/8
     * 参数：

     * 返回值：
     **/
    public int setAideJoinSetting(int activityId, boolean onlyUnionMemberJoin){
        checkUserData();
        if(null == userPalaceData){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }
        PalaceActivityMgr.sendPalaceAideSetting(activityId, player.getUserId(), onlyUnionMemberJoin, true);
        return 0;
    }

    /**
    * 描述：膜拜
    * 作者：zrq
    * 时间：2022/2/11
    * 参数：

    * 返回值：
    **/
    public int worship(){
        checkUserData();
        if(null == userPalaceData){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }
        long zeroTime = LocalDateTimeHelper.getZeroTimeTimeStamp();
        if(userPalaceData.getWorshipTime() > zeroTime){
            return GameErrorCode.E_ESTATE_WAR_WORSHIP_ALREADY;
        }
        //发到跨服
        EstateWarProto.PalaceWorshipReqMsg.Builder crossMsg = EstateWarProto.PalaceWorshipReqMsg.newBuilder();
        crossMsg.setActivityId(userPalaceData.getActivityId());
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_PALACE_WORSHIP, crossMsg);
        GamePlayerMgr.sendPacket(player.getUserId(), pbMsg);
        return 0;
    }

    public  EstateWarProto.PalaceWorshipRespMsg.Builder worshipResponse(EstateWarProto.PalaceWorshipRespMsg reqMsg){
        EstateWarProto.PalaceWorshipRespMsg.Builder respMsg = EstateWarProto.PalaceWorshipRespMsg.newBuilder();
        if(reqMsg.getRet() != 0){
            respMsg.setRet(reqMsg.getRet());
            return respMsg;
        }
        checkUserData();
        if(null == userPalaceData){
            respMsg.setRet(GameErrorCode.E_SYSTEM_NO_OPEN);
            return respMsg;
        }
        long zeroTime = LocalDateTimeHelper.getZeroTimeTimeStamp();
        if(userPalaceData.getWorshipTime() > zeroTime){
            respMsg.setRet(GameErrorCode.E_ESTATE_WAR_WORSHIP_ALREADY);
            return respMsg;
        }
        userPalaceData.setWorshipTime(System.currentTimeMillis());
        //加奖励
        PalaceActivity palaceActivity = PalaceActivityMgr.getInTimePalaceActivity();
        Property reward;
        if(null != palaceActivity){
            reward = palaceActivity.getWorshipReward();
        }else {
            reward = new Property();
        }
        player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.EstateWar, eLogMoneyType.PalaceWorship);
        //同步
        syncUserData();
        AutoLogMgr.add(new LogPalaceWorship(userPalaceData.getActivityId(), player.getUserId(), reqMsg.getUserData().getUserId(),
                reqMsg.getUserData().getPos(), PropertyHelper.parsePropertyToString(reward)));
        respMsg.setRet(0);
        respMsg.setUserData(reqMsg.getUserData().toBuilder());
        respMsg.setReward(PropertyHelper.parsePropertyToString(reward));
        return respMsg;
    }

    public void addBattleRecord(PalaceBattleRecord data){
        synchronized (palaceBattleRecordList) {
            palaceBattleRecordList.add(data);
            while (palaceBattleRecordList.size() > GameConfig.PALACE_BATTLE_RECORD_MAX_COUNT){
                PalaceBattleRecord tempData = palaceBattleRecordList.get(0);
                if(!tempData.isDirty()){
                    palaceBattleRecordList.remove(0);
                }else {
                    break;
                }
            }
        }
        syncBattleRecord(data);
    }

    public List<PalaceBattleRecord> getPalaceBattleRecordList() {
        List<PalaceBattleRecord> dataList;
        synchronized (palaceBattleRecordList){
            dataList = new ArrayList<>(palaceBattleRecordList);
        }
        int length = dataList.size();
        if(length > GameConfig.PALACE_BATTLE_RECORD_MAX_COUNT){
            dataList.sort(Comparator.comparingLong(PalaceBattleRecord::getRecordTime));
            dataList = dataList.subList(length - GameConfig.PALACE_BATTLE_RECORD_MAX_COUNT, length);
        }
        return dataList;
    }
}
